package io.itit.ecp.admin.provide.action.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.common.enums.ProductTypeActiveStatus;
import io.itit.ecp.admin.provide.action.req.ProductTypeQueryReq;
import io.itit.ecp.admin.provide.action.req.ProductTypeReq;
import io.itit.ecp.admin.provide.action.resp.ProductTypeResp;
import io.itit.ecp.admin.provide.renderer.ProductTypeRenderer;
import io.itit.ecp.admin.server.entity.ProductTypeEntity;
import io.itit.ecp.admin.server.service.IProductTypeService;
import io.itit.grass.common.exception.GrassException;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.*;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.estelle.starter.core.ExcelXSSFUtil;
import io.itit.grass.estelle.starter.parse.ExcelParseManage;
import io.itit.grass.estelle.starter.util.JsonUtil;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：产品类型控制类
 * @Date：Create by 2023-12-02 20:13:28
 */
@Api(tags = "产品类型")
@RestController
@RequestMapping("/ecp-admin/productType")
public class ProductTypeController {

    @Resource
    private IProductTypeService productTypeService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:productType:search")
    public ResultResp<IPage<ProductTypeResp>> queryPage(@RequestBody @Validated(IQueryPage.class) ProductTypeQueryReq req) {
        Page<ProductTypeEntity> page = productTypeService.page(PageUtils.getPage(req, ProductTypeEntity.class), buildQW(req));
        return ResultResp.success(ConvertUtils.convert(page, ProductTypeResp.class));
    }

    @ApiOperation("详情")
    @PostMapping("detail")
    @RequiresPermissions("ecp-admin:productType:search")
    public ResultResp<ProductTypeResp> detail(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        return ResultResp.success(ConvertUtils.copy(productTypeService.getById(req.getId()), ProductTypeResp.class));
    }

    /**
     * 组装查询条件
     */
    private static LambdaQueryWrapper<ProductTypeEntity> buildQW(ProductTypeQueryReq req) {
        LocalDateTime start = null;
        LocalDateTime end = null;
        if (StringUtils.isNotEmpty(req.getCreateTm())) {
            LocalDate date = LocalDate.parse(req.getCreateTm(), DateTimeFormatter.ofPattern("MM/dd/yyyy"));
            start = date.atTime(LocalTime.MIN);
            end = date.atTime(LocalTime.MAX);
        }
        return Wrappers.<ProductTypeEntity>lambdaQuery()
                .like(StringUtils.isNotEmpty(req.getProductTypeCode()), ProductTypeEntity::getProductTypeCode, req.getProductTypeCode())
                .like(StringUtils.isNotEmpty(req.getProductTypeName()), ProductTypeEntity::getProductTypeName, req.getProductTypeName())
                .eq(req.getSort() != null, ProductTypeEntity::getSort, req.getSort())
                .eq(StringUtils.isNotEmpty(req.getDeptId()), ProductTypeEntity::getDeptId, req.getDeptId())
                .in(CollectionUtils.isNotEmpty(req.getIds()), ProductTypeEntity::getId, req.getIds())
                .ge(Objects.nonNull(start), ProductTypeEntity::getCreateTm, start)
                .le(Objects.nonNull(end), ProductTypeEntity::getCreateTm, end)
                .last(StringUtils.isNotEmpty(req.getSortColumn()), PageUtils.lastOrderBy(req))
                .orderByAsc(StringUtils.isEmpty(req.getSortColumn()), ProductTypeEntity::getSort)
                .orderByDesc(StringUtils.isEmpty(req.getSortColumn()), ProductTypeEntity::getCreateTm);
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:productType:add")
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) ProductTypeReq req) {
        checkDataExists(req);
        ProductTypeEntity productTypeEntity = ConvertUtils.convertIgnoreId(req, ProductTypeEntity.class);
        productTypeEntity.setActiveStatus(ProductTypeActiveStatus.ENABLED.getValue());
        return ResultResp.success(productTypeService.save(productTypeEntity));
    }

    @ApiOperation("启用")
    @PostMapping("enable")
    public ResultResp<Boolean> enable(@RequestBody @Validated({IUpdate.class}) ProductTypeReq req) {
        ProductTypeEntity productTypeEntity = productTypeService.getById(req.getId());
        productTypeEntity.setActiveStatus(ProductTypeActiveStatus.ENABLED.getValue());
        return ResultResp.success(productTypeService.updateById(productTypeEntity));
    }

    @ApiOperation("禁用")
    @PostMapping("disable")
    public ResultResp<Boolean> disable(@RequestBody @Validated({IUpdate.class}) ProductTypeReq req) {
        ProductTypeEntity productTypeEntity = productTypeService.getById(req.getId());
        productTypeEntity.setActiveStatus(ProductTypeActiveStatus.DISABLED.getValue());
        return ResultResp.success(productTypeService.updateById(productTypeEntity));
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @RequiresPermissions("ecp-admin:productType:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) ProductTypeReq req) {
        checkDataExists(req);
        ProductTypeEntity productTypeEntity = ConvertUtils.copy(req, ProductTypeEntity.class);
        productTypeEntity.setActiveStatus(IMeterDeviceEnums.DelFlag.delFlag1.delFlag);
        return ResultResp.success(productTypeService.updateById(productTypeEntity));
    }

    private void checkDataExists(ProductTypeReq req) {
        Long count = productTypeService.lambdaQuery()
                .eq(ProductTypeEntity::getProductTypeName, req.getProductTypeName())
                .ne(StringUtils.isNotEmpty(req.getId()), ProductTypeEntity::getId, req.getId())
                .count();
        GrassException.throwEx(count > 0, "产品类型名称已存在！");
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:productType:deleteById")
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        return ResultResp.success(productTypeService.removeById(req.getId()));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:productType:batchDelete")
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        return ResultResp.success(productTypeService.removeBatchByIds(req.getIds(), 200));
    }

    @ApiOperation("导入")
    @PostMapping("upload")
    @RequiresPermissions("ecp-admin:productType:upload")
    public ResultResp<Integer> upload(@RequestParam("file") MultipartFile file, Boolean ignoreError) {
        return ResultResp.success(ExcelParseManage.i().process(ProductTypeRenderer.ENTITY_NAME, file, ignoreError));
    }

    @ApiOperation("导出")
    @PostMapping("export")
    @RequiresPermissions("ecp-admin:productType:export")
    public void export(@RequestBody @Validated(IExport.class) ProductTypeQueryReq req, HttpServletResponse response) {
        ExcelXSSFUtil.export("ProductTypeExport", JsonUtil.toJson(productTypeService.list(buildQW(req))), response);
    }
}
